<?php
/**
 * Created by PhpStorm.
 * User: ownfi
 * Date: 2017-03-13
 * Time: 19:45
 */

namespace App\Services\Impl;

use App\Common\Constant\CacheKey;
use App\Common\Constant\Params;
use App\Models\AlipayLog;
use App\Models\Banner;
use App\Models\EventLog;
use App\Models\HistorySystemBalance;
use App\Models\Province;
use App\Models\SmsLog;
use App\Models\SystemAccount;
use App\Models\SystemSchema;
use App\Services\ISystemService;
use Cache;
use DB;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Client;
use Log;

class SystemServiceImpl implements ISystemService
{

    public function genOrderNumber()
    {
        return 'LB'.date('ymdHis').random(6,'UCNUMBER');
    }

    public function genTradeNumber()
    {
        return date('ymdHis').sprintf('%u',crc32(microtime(true))).random(8,'UCNUMBER');
    }

    public function genInsideOrderNumber()
    {
        return 'LBIN'.date('ymdHis').random(6,'UCNUMBER');
    }

    public function genCouponNumber()
    {
        return 'CP'.date('ymdHis').random(6,'NUMBER');
    }

    public function success($message)
    {
        session()->flash('success',$message);
    }

    public function alert($message)
    {
        session()->flash('alert',$message);
    }

    public function smsLogList(array $wheres = [])
    {
        $model = SmsLog::alias('t1')->select('t1.*')->orderBy('t1.sl_add_time','DESC');
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function subtractBalance($trade_id,$user_id,$user_type,$amount)
    {
        $history = HistorySystemBalance::where('trade_id',$trade_id)->where('user_id',$user_id)->first();
        if ($history && ($history->direction == Params::TRADE_DIRECTION_OUT)){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'trade history already exists'));
            return true;
        }

        DB::beginTransaction();
        try{
            $amount = floatval($amount);

            $model = new SystemAccount();
            if (empty($model->wallet_balance) || ($model->wallet_balance < $amount)){
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'balance not enough'));
                DB::rollBack();
                return false;
            }

            $current_balance = $model->wallet_balance;
            $new_balance = $current_balance - $amount;
            $model->wallet_balance = $new_balance;

            $ret = HistorySystemBalance::create([
                    'trade_id'=>$trade_id,
                    'user_id'=>$user_id,
                    'user_type'=>$user_type,
                    'direction'=>Params::TRADE_DIRECTION_OUT,
                    'amount'=>$amount,
                    'current_balance'=>$current_balance,
                    'new_balance'=>$new_balance,
                ]) && $model->apply();

            if ($ret){
                DB::commit();
            }else{
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'subtract fail'));
                DB::rollBack();
            }
            return $ret;
        }catch (\Exception $e){
            DB::rollBack();
            throw $e;
        }
    }

    public function raiseBalance($trade_id,$user_id,$user_type,$amount)
    {
        $history = HistorySystemBalance::where('trade_id',$trade_id)->where('user_id',$user_id)->first();
        if ($history && ($history->direction == Params::TRADE_DIRECTION_IN)){
            Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'trade history already exists'));
            return true;
        }

        DB::beginTransaction();
        try{
            $amount = floatval($amount);

            $model = new SystemAccount();
            $current_balance = $model->wallet_balance;
            $new_balance = $current_balance + $amount;
            $model->wallet_balance = $new_balance;

            $ret = HistorySystemBalance::create([
                    'trade_id'=>$trade_id,
                    'user_id'=>$user_id,
                    'user_type'=>$user_type,
                    'direction'=>Params::TRADE_DIRECTION_IN,
                    'amount'=>$amount,
                    'current_balance'=>$current_balance,
                    'new_balance'=>$new_balance,
                ]) && $model->apply();

            if ($ret){
                DB::commit();
            }else{
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'raise fail'));
                DB::rollBack();
            }
            return $ret;
        }catch (\Exception $e){
            DB::rollBack();
            throw $e;
        }
    }

    public function requestUrl($url, $data = null, $method = 'GET')
    {
        Log::info("System request method: {$method}, url: {$url}",(array)$data);
        try {
            $client = new Client();
            $response = $client->request($method, $url, [
                'query' => $data ? (array)$data : []
            ]);
            return $response->getStatusCode() == 200 ? $response->getBody() : false;
        } catch (RequestException $e) {
            throw $e;
        }
    }

    public function alipayLogList(array $wheres = [])
    {
        $model = AlipayLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC');
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function notifyLogList(array $wheres = [])
    {
        $model = EventLog::alias('t1')->select('t1.*')->orderBy('t1.add_time','DESC');
        if ($wheres){
            $model->where($wheres);
        }
        return $model->paginate(config('common.perpage'));
    }

    public function bannerList()
    {
        return Banner::orderBy('sort','ASC')->orderBy('add_time','DESC')->get();
    }

}